#include "wl_dns.h"

#include "wl_dns_inner.h"
#include "wl_malloc.h"
#include "wl_ext_network.h"
#include "wl_trace.h"


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define MAX_HOST_LEN 80  //长度不能大于80,wl_dns_message直接使用系统消息结构 size不能大于WL_MESSAGE_QUEUE_MSG_DATA_SIZE
#define MAX_IP_LEN 20

typedef struct __wl_dns_message {
    wl_int32        resultcode;
    wl_char         host_name[MAX_HOST_LEN];
    wl_char         host[MAX_IP_LEN];
    wl_dns_callback callback;
    void*           context;
} wl_dns_message;

typedef struct __wl_dns_param {
    wl_char         host_name[MAX_HOST_LEN];
    wl_dns_callback callback;
    void*           context;
    wl_int32        taskid;
} wl_dns_param;

static void wl_ext_get_dns_callback(int resultCode,const char* ip, void* context) {
    wl_dns_param*   dns_param = (wl_dns_param*)context;
    wl_dns_message  dns_message;
    wl_task_message message;

    memset(&dns_message, 0, sizeof(dns_message));

    if (resultCode == WL_EXT_NETWORK_SUCCESS) {
        dns_message.resultcode = WL_DNS_SUCCESS;
    } else {
        dns_message.resultcode = WL_DNS_TIMEOUT;
    }

    strncpy(dns_message.host_name, dns_param->host_name, sizeof(dns_message.host_name));
    dns_message.host_name[sizeof(dns_message.host_name) - 1] = '\0';
    dns_message.host[sizeof(dns_message.host) - 1]           = '\0';
    dns_message.callback                                     = dns_param->callback;
    dns_message.context                                      = dns_param->context;
    WLLOGI("dns host %s ip %s", dns_param->host_name, dns_message.host);
    //发送消息
    memset(&message, 0, sizeof(wl_task_message));
    message.type = WL_TASK_MSG_DNS;
    memcpy(&message.data, &dns_message, sizeof(wl_dns_message));
    message.datalen = sizeof(wl_dns_message);
    wl_send_task_message(dns_param->taskid, &message);

    wl_free(context); 
}

wl_int32 wl_dns_async_gethostbyname(wl_char* host_name, wl_dns_callback callback, void* context, wl_int32 taskid) {
    wl_dns_param*   dns_param = (wl_dns_param*)wl_malloc(sizeof(wl_dns_param));
    wl_dns_message  dns_message;
    wl_task_message message;

    if (wl_null == dns_param) {
        WLLOGW("malloc fail");
        return -1;
    }
    if (wl_null == host_name || strlen(host_name) <= 0) {
        WLLOGW("host name invalid");
        wl_free(dns_param);
        return -1;
    }

    //发送DNS处理中
    memset(&dns_message, 0, sizeof(wl_dns_message));
    strncpy(dns_message.host_name, host_name, sizeof(dns_message.host_name));
    dns_message.resultcode = WL_DNS_PROCESSING;
    dns_message.callback   = callback;
    dns_message.context    = context;
    memset(&message, 0, sizeof(wl_task_message));
    message.type = WL_TASK_MSG_DNS;
    memcpy(&message.data, &dns_message, sizeof(wl_dns_message));
    message.datalen = sizeof(wl_dns_message);
    wl_send_task_message(taskid, &message);

    memset(dns_param, 0, sizeof(wl_dns_param));
    strncpy(dns_param->host_name, host_name, sizeof(dns_param->host_name));
    dns_param->host_name[sizeof(dns_param->host_name) - 1] = '\0';
    dns_param->callback                                    = callback;
    dns_param->context                                     = context;
    dns_param->taskid                                      = taskid;

    wl_ext_get_host_by_name_async(dns_param->host_name, wl_ext_get_dns_callback, dns_param);
    return 0;
}

wl_int32 wl_dns_gethostbyname(wl_char* host_name, wl_char* host) {
    WLLOGW("host_name %s no ip", host_name);
    return wl_ext_get_host_by_name_sync(host_name, host);
}

wl_int32 wl_dns_process_message(wl_task_message* message) {
    wl_dns_message dns_message;
    if (wl_null == message || sizeof(wl_dns_message) != message->datalen) {
        WLLOGW("message is null");
        return -1;
    }
    memcpy(&dns_message, &(message->data), message->datalen);
    if (dns_message.callback) {
        dns_message.callback(dns_message.resultcode, dns_message.host_name, dns_message.host, dns_message.context);
    }
    return 0;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
